package cn.wizzer.app.user.modules.service.impl;

import cn.wizzer.app.user.modules.models.GroupInfo;
import cn.wizzer.app.user.modules.models.GroupLog;
import cn.wizzer.app.user.modules.models.GroupMember;
import cn.wizzer.app.user.modules.models.User;
import cn.wizzer.app.user.modules.models.enums.MsgTypeEnum;
import cn.wizzer.app.user.modules.models.enums.OprTypeEnum;
import cn.wizzer.app.user.modules.models.vo.GroupMsgVO;
import cn.wizzer.app.user.modules.models.vo.GroupVO;
import cn.wizzer.app.user.modules.services.GroupInfoService;
import cn.wizzer.app.user.modules.services.GroupLogService;
import cn.wizzer.app.user.modules.services.GroupMemberService;
import cn.wizzer.app.user.modules.services.UserService;
import cn.wizzer.framework.base.service.BaseServiceImpl;
import cn.wizzer.framework.base.service.CommonDBService;
import cn.wizzer.framework.page.Pagination;
import com.alibaba.dubbo.config.annotation.Service;
import org.nutz.aop.interceptor.ioc.TransAop;
import org.nutz.dao.Chain;
import org.nutz.dao.Cnd;
import org.nutz.dao.Dao;
import org.nutz.dao.Sqls;
import org.nutz.dao.sql.Sql;
import org.nutz.ioc.aop.Aop;
import org.nutz.ioc.loader.annotation.Inject;
import org.nutz.ioc.loader.annotation.IocBean;
import org.nutz.lang.Strings;
import org.nutz.lang.Times;

import java.util.List;

@IocBean(args = {"refer:dao"})
@Service(interfaceClass = GroupInfoService.class)
public class GroupInfoServiceImpl extends BaseServiceImpl<GroupInfo> implements GroupInfoService {
    public GroupInfoServiceImpl(Dao dao) {
        super(dao);
    }

    @Inject
    private CommonDBService dbService;
    @Inject
    private GroupMemberService groupMemberService;
    @Inject
    private GroupLogService groupLogService;
    @Inject
    private UserService userService;

    @Override
    public List<GroupMsgVO> list(String userId) {
        Sql sql = Sqls.create("SELECT i.*, m.unReadCount " +
                "FROM group_member m " +
                "LEFT JOIN group_info i ON i.id = m.groupId " +
                "WHERE m.userId = @userId " +
                "AND m.delFlag = 0 ");
        sql.setParam("userId", userId);
        List<GroupMsgVO> list = dbService.list(GroupMsgVO.class, sql.toString());
        //查询各个群的最后一条消息记录
        for (GroupMsgVO groupMsgVO : list) {
            GroupLog groupLog = groupLogService.fetch(Cnd.where("groupId", "=", groupMsgVO.getId()).orderBy("ctAt", "desc"));
            if (groupLog != null) {
                User user = userService.fetch(groupLog.getUserId());
                groupMsgVO.setMsgId(groupLog.getId());
                groupMsgVO.setMsgSenderId(groupLog.getUserId());
                groupMsgVO.setMsgOprType(groupLog.getOprType());
                groupMsgVO.setMsgType(groupLog.getMsgType());
                groupMsgVO.setMsgContent(groupLog.getContent());
                groupMsgVO.setSendTime(groupLog.getCtAt());
                groupMsgVO.setNickname(user.getNickName());
                groupMsgVO.setUsername(user.getUserName());
                groupMsgVO.setHeadPicture(user.getHeadPicture());
            }
        }
        return list;
    }

    @Override
    public Pagination listPage(int pageNumber, int pageSize, String searchKeyword) {
        Sql sql = Sqls.create("select i.*,u.nickname from group_info i ");
        Sql countSql = Sqls.create("select count(1) from group_info i ");
        Sql joinSql = Sqls.create("left join user u on u.id = i.masterId " +
                "$condition ");
        Cnd cnd = Cnd.where("i.delFlag", "=", 0);
        if (Strings.isNotBlank(searchKeyword)) {
            searchKeyword = "%" + searchKeyword + "%";
            cnd.and(Cnd.exps("i.groupName", "like", searchKeyword)
                    .or("u.nickName", "like", searchKeyword)
                    .or("u.phone", "like", searchKeyword)
                    .or("u.userName", "like", searchKeyword));
        }
        joinSql.setCondition(cnd);
        sql.appendSourceSql(joinSql.toString());
        sql.appendSourceSql("order by ctAt desc");
        countSql.appendSourceSql(joinSql.toString());
        return dbService.listPage(GroupVO.class, pageNumber, pageSize, sql.toString(), countSql.toString());
    }

    /**
     * 查询未入该群用户
     *
     * @param pageNumber
     * @param pageSize
     * @param groupId
     * @param searchKeyword
     * @return
     */
    @Override
    public Pagination memberList(int pageNumber, int pageSize, String groupId, String searchKeyword) {
        //查询已入群的用户id
        Sql groupMemberSql = Sqls.create("SELECT userId FROM group_member WHERE groupId = @groupId AND delFlag = 0");
        groupMemberSql.setParam("groupId", groupId);
        groupMemberSql.setCallback(Sqls.callback.strs());
        groupMemberService.execute(groupMemberSql);
        List<String> list = groupMemberSql.getList(String.class);
        Sql sql = Sqls.create("SELECT id, nickName, phone, userName, headPicture " +
                "FROM user " +
                "$condition ");
        Sql countSql = Sqls.create("SELECT COUNT(1) FROM user " +
                "$condition ");
        Cnd cnd = Cnd.where("id", "NOT IN ", list);
        if (Strings.isNotBlank(searchKeyword)) {
            searchKeyword = "%" + searchKeyword + "%";
            cnd.and(Cnd.exps("nickName", "LIKE", searchKeyword)
                    .or("phone", "LIKE", searchKeyword)
                    .or("userName", "LIKE", searchKeyword));
        }
        sql.setCondition(cnd);
        sql.appendSourceSql("ORDER BY lastLoginAt DESC");
        countSql.setCondition(cnd);
        return userService.listPage(pageNumber, pageSize, sql, countSql);
    }

    /**
     * 编辑群
     *
     * @param groupInfo
     */
    @Aop(TransAop.READ_COMMITTED)
    @Override
    public void edit(GroupInfo groupInfo, String opBy) {
        GroupInfo oldGroupInfo = this.fetch(groupInfo.getId());
        //当更换群主时，删除原群主，新群主若不再群里则添加新成员
        if (!oldGroupInfo.getMasterId().equals(groupInfo.getMasterId())) {
            //将排序等级改为群员，开启删除标记
            groupMemberService.update(Chain.make("sort", 1).add("delFlag", 1),
                    Cnd.where("userId", "=", oldGroupInfo.getMasterId())
                            .and("groupId", "=", oldGroupInfo.getId()));
            GroupMember groupMember = groupMemberService.fetch(Cnd.where("userId", "=", groupInfo.getMasterId())
                    .and("groupId", "=", groupInfo.getId()));
            if (groupMember == null) {
                groupMember = new GroupMember();
                groupMember.setUserId(groupInfo.getMasterId());
                groupMember.setGroupId(groupInfo.getId());
                groupMember.setSort(0);
                groupMemberService.insert(groupMember);
            } else {
                groupMember.setSort(0);
                groupMember.setDelFlag(false);
                groupMemberService.update(groupMember);
            }
            //添加消息记录
            String content = "管理员更换了群主，现群主 " + userService.fetch(groupMember.getUserId()).getNickName();
            groupLogService.groupSend(oldGroupInfo.getMasterId(), oldGroupInfo.getId(), content, MsgTypeEnum.TEXT, OprTypeEnum.REMOVED, true);
        }
        this.update(Chain.make("groupName", groupInfo.getGroupName())
                .add("groupHeadPicture", groupInfo.getGroupHeadPicture())
                .add("masterId", groupInfo.getMasterId())
                .add("opAt", Times.getTS())
                .add("opBy", opBy), Cnd.where("id", "=", groupInfo.getId()));
    }

    /**
     * 添加群
     *
     * @param groupInfo
     */
    @Aop(TransAop.READ_COMMITTED)
    @Override
    public void add(GroupInfo groupInfo) {
        groupInfo = this.insert(groupInfo);
        //添加群主
        GroupMember groupMember = new GroupMember();
        groupMember.setUserId(groupInfo.getMasterId());
        groupMember.setGroupId(groupInfo.getId());
        groupMember.setSort(0);
        groupMemberService.insert(groupMember);

    }
}
